In [1]:
from IPython.display import HTML
HTML('''<script>
code_show=true; 
function code_toggle() {
 if (code_show){
 $('div.input').hide();
 } else {
 $('div.input').show();
 }
 code_show = !code_show
} 
$( document ).ready(code_toggle);
</script>
The raw code for this IPython notebook is by default hidden for easier reading.
To toggle on/off the raw code, click <a href="javascript:code_toggle()">here</a>.''')
Out[1]:
The raw code for this IPython notebook is by default hidden for easier reading. To toggle on/off the raw code, click here.
In [2]:
import sys
import os
sys.path.append(os.path.join(os.path.split(os.path.abspath(''))[0], 'project/packages'))

# For writing images
if not os.path.exists("images"):
    os.mkdir("images")
In [3]:
import pandas as pd
import plotly.express as px
import plotly.graph_objects as go
import ipywidgets as widgets

import data_types
import stock_data_manager
import stock_data_consumer

CASH_OUT_PCT=0
CASH_OUT_AMMOUNT=0
CASH_OUT_DAY=0

portfolio_name = 'sample'
use_latest_quote = True
save_graphs = False

sdm = stock_data_manager.StockDataManager(console_logging_level='ERROR', portfolio_name=portfolio_name)
sdm._testing = True
sdm.run()

sdc = stock_data_consumer.StockDataConsumer(all_symbols=sdm.all_symbols,
                                            stock_categories=sdm.stock_categories,
                                            category_allocations=sdm.category_allocations,
                                            index_tracker_stocks=sdm.index_tracker_stocks,
                                            watchlist_stocks=sdm.watchlist_stocks,
                                            portfolio_stocks=sdm.portfolio_stocks,
                                            positions=sdm.positions,
                                            use_latest_quote=use_latest_quote)
sdc.run()

portfolio_stock_stats_combined = sdc.get_portfolio_stock_stats(combined=True)
portfolio_aggregated_stats = sdc.get_portfolio_aggregate_stats()
portfolio_index_comparison_stats = sdc.get_portfolio_index_comparison_stats()
portfolio_index_day_comparison_stats = sdc.get_portfolio_index_day_comparison_stats()
portfolio_stock_comparison_stats = sdc.get_portfolio_stock_comparison_stats()
portfolio_watchlist_comparison_stats = sdc.get_portfolio_watchlist_comparison_stats()
portfolio_stock_composition_stats = sdc.get_portfolio_stock_composition_stats()
portfolio_category_composition_stats = sdc.get_portfolio_category_composition_stats()
portfolio_category_composition_stats_combined = sdc.get_portfolio_category_composition_stats(combined=True)

portfolio_market_dates = sdc.portfolio_market_dates
first_date = portfolio_market_dates[0]
last_date = portfolio_market_dates[len(portfolio_market_dates)-1]
cash_out_date = portfolio_market_dates[CASH_OUT_DAY]
# Pick last date for any outputs
s_composition_stats = portfolio_stock_composition_stats[last_date]
c_composition_stats = portfolio_category_composition_stats[last_date]
In [4]:
min_value = portfolio_aggregated_stats['total_pct_gain'].min()
max_value = portfolio_aggregated_stats['total_pct_gain'].max()

fig = px.line(portfolio_aggregated_stats, 
              x='date', y="total_pct_gain", 
              hover_data=['invested_amount', 'market_value', 'unrealized_gain', 
                          'unrealized_pct_gain', 'realized_gain', 'realized_pct_gain', 
                          'total_gain', 'total_pct_gain'],
              range_y=[min_value, max_value+1],
              title='Portfolio Value')
fig.update_xaxes(
    rangeslider_visible=True,
    rangeselector=dict(
        buttons=list([
            dict(count=1, label="1m", step="month", stepmode="backward"),
            dict(count=6, label="6m", step="month", stepmode="backward"),
            dict(count=1, label="YTD", step="year", stepmode="todate"),
            dict(count=1, label="1y", step="year", stepmode="backward"),
            dict(step="all")
        ])
    )
)
fig.add_shape(
        # Rectangle reference to the axes
            type="rect",
            xref="x",
            yref="y",
            x0=first_date,
            y0=min_value,
            x1=last_date,
            y1=0,
            opacity=0.2,
            fillcolor="Red",
        )
fig.add_shape(
        # Line Horizontal
            type="line",
            x0=first_date,
            y0=CASH_OUT_PCT,
            x1=last_date,
            y1=CASH_OUT_PCT,
            line=dict(
                color="Green",
                width=1,
                dash="dashdot",
            ),
    )
fig.add_shape(
        # Line Vertical
        dict(
            type="line",
            x0=cash_out_date,
            y0=min_value,
            x1=cash_out_date,
            y1=max_value,
            line=dict(
                color="Orange",
                width=1,
                dash="dashdot",
            )
))
fig.show()

if save_graphs:
    fig.write_image("images/portfolio_value.pdf")
In [5]:
min_value = portfolio_aggregated_stats['total_gain'].min()
max_value = portfolio_aggregated_stats['total_gain'].max()

fig = px.line(portfolio_aggregated_stats, 
              x='date', y="total_gain", 
              hover_data=['invested_amount', 'market_value', 'unrealized_gain', 
                          'unrealized_pct_gain', 'realized_gain', 'realized_pct_gain', 
                          'total_gain', 'total_pct_gain'],
              range_y=[min_value, max_value+1],
              color_discrete_sequence=["limegreen"],
              title='Total Gain')
fig.update_xaxes(
    rangeslider_visible=True,
    rangeselector=dict(
        buttons=list([
            dict(count=1, label="1m", step="month", stepmode="backward"),
            dict(count=6, label="6m", step="month", stepmode="backward"),
            dict(count=1, label="YTD", step="year", stepmode="todate"),
            dict(count=1, label="1y", step="year", stepmode="backward"),
            dict(step="all")
        ])
    )
)
fig.add_shape(
        # Rectangle reference to the axes
            type="rect",
            xref="x",
            yref="y",
            x0=first_date,
            y0=min_value,
            x1=last_date,
            y1=0,
            opacity=0.2,
            fillcolor="Red",
        )
fig.add_shape(
        # Line Horizontal
            type="line",
            x0=first_date,
            y0=CASH_OUT_AMMOUNT,
            x1=last_date,
            y1=CASH_OUT_AMMOUNT,
            line=dict(
                color="Blue",
                width=0.5,
                dash="dashdot",
            ),
    )
fig.add_shape(
        # Line Vertical
        dict(
            type="line",
            x0=cash_out_date,
            y0=min_value,
            x1=cash_out_date,
            y1=max_value,
            line=dict(
                color="Orange",
                width=1.5,
                dash="dashdot",
            )
))

fig.show()

if save_graphs:
    fig.write_image("images/total_gain.pdf")
In [6]:
min_value = portfolio_aggregated_stats['annualized_pct_return'].min()
max_value = portfolio_aggregated_stats['annualized_pct_return'].max()

fig = px.line(portfolio_aggregated_stats, 
                 x="date", y="annualized_pct_return", 
                 hover_data=['invested_amount', 'market_value', 'unrealized_gain', 
                             'unrealized_pct_gain', 'realized_gain', 'realized_pct_gain', 
                             'total_gain', 'total_pct_gain', 'annualized_pct_return', 'days_elapsed'],
                 range_y=[min_value, max_value+1],
                 color_discrete_sequence=["black"],
                 title='Portfolio Annualized Return')
fig.update_xaxes(
    rangeslider_visible=True,
    rangeselector=dict(
        buttons=list([
            dict(count=1, label="1m", step="month", stepmode="backward"),
            dict(count=6, label="6m", step="month", stepmode="backward"),
            dict(count=1, label="YTD", step="year", stepmode="todate"),
            dict(count=1, label="1y", step="year", stepmode="backward"),
            dict(step="all")
        ])
    )
)
fig.add_shape(
        # Rectangle reference to the axes
            type="rect",
            xref="x",
            yref="y",
            x0=first_date,
            y0=min_value,
            x1=last_date,
            y1=0,
            opacity=0.3,
            fillcolor="Red",
        )
fig.add_shape(
        # Rectangle reference to the axes
            type="rect",
            xref="x",
            yref="y",
            x0=first_date,
            y0=100,
            x1=last_date,
            y1=max_value,
            opacity=0.3,
            fillcolor="Green",
        )
fig.add_shape(
            type="rect",
            xref="x",
            yref="y",
            x0=first_date,
            y0=0,
            x1=last_date,
            y1=100,
            opacity=0.3,
            fillcolor="DarkOrange",
        )
fig.add_shape(
        # Line Vertical
        dict(
            type="line",
            x0=cash_out_date,
            y0=min_value,
            x1=cash_out_date,
            y1=max_value,
            line=dict(
                color="Blue",
                width=1,
                dash="dashdot",
            )
))

fig.show()

if save_graphs:
    fig.write_image("images/portfolio_annualized_return.pdf")
In [7]:
min_value = portfolio_aggregated_stats['total_pct_gain'].min()
max_value = portfolio_aggregated_stats['total_pct_gain'].max()

fig = px.scatter(portfolio_aggregated_stats, 
                 x="date", y="total_pct_gain", 
                 trendline="lowess",
                 hover_data=['invested_amount', 'market_value', 'unrealized_gain', 
                             'unrealized_pct_gain', 'realized_gain', 'realized_pct_gain', 
                             'total_gain', 'total_pct_gain'],
                 marginal_y='box',
                 color='invested_amount',
                 range_y=[min_value, max_value+1],
                 trendline_color_override='dodgerblue',
                 title='Portfolio Value Scatter')
fig.update_xaxes(
    rangeselector=dict(
        buttons=list([
            dict(count=1, label="1m", step="month", stepmode="backward"),
            dict(count=6, label="6m", step="month", stepmode="backward"),
            dict(count=1, label="YTD", step="year", stepmode="todate"),
            dict(count=1, label="1y", step="year", stepmode="backward"),
            dict(step="all")
        ])
    )
)
fig.add_shape(
        # Rectangle reference to the axes
            type="rect",
            xref="x",
            yref="y",
            x0=first_date,
            y0=min_value,
            x1=last_date,
            y1=0,
            opacity=0.2,
            fillcolor="Red",
        )
fig.add_shape(
        # Line Horizontal
            type="line",
            x0=first_date,
            y0=CASH_OUT_PCT,
            x1=last_date,
            y1=CASH_OUT_PCT,
            line=dict(
                color="Green",
                width=1,
                dash="dashdot",
            ),
    )
fig.add_shape(
        # Line Vertical
        dict(
            type="line",
            x0=cash_out_date,
            y0=min_value,
            x1=cash_out_date,
            y1=max_value,
            line=dict(
                color="Blue",
                width=1,
                dash="dashdot",
            )
))

fig.show()

if save_graphs:
    fig.write_image("images/portfolio_value_scatter.pdf")
In [8]:
fig = px.bar(c_composition_stats.sort_values(by='composition_invested', ascending=False), 
             x="composition_invested", 
             y="category", 
             title='Current Allocation', 
             hover_data=['desired_allocation'],
             color="category", 
             text="composition_invested", 
             orientation='h')

fig.show()

if save_graphs:
    fig.write_image("images/current_allocation.pdf")
In [9]:
fig = px.bar(c_composition_stats, 
             x="desired_composition_invested_diff", y="category", 
             title='Allocation Difference', 
             color="category", 
             text="desired_composition_invested_diff", 
             hover_data=['desired_allocation'],
             orientation='h')

fig.show()

if save_graphs:
    fig.write_image("images/allocation_difference.pdf")
In [10]:
min_value = portfolio_index_comparison_stats['total_pct_gain'].min()
max_value = portfolio_index_comparison_stats['total_pct_gain'].max()

fig = px.line(portfolio_index_comparison_stats, 
              x='date', y="total_pct_gain", 
              hover_data=['market_value', 'total_pct_gain'],
              range_y=[min_value, max_value+1],
              color='symbol',
              title='Portfolio Index Comparisons')
fig.update_xaxes(
    rangeslider_visible=True,
    rangeselector=dict(
        buttons=list([
            dict(count=1, label="1m", step="month", stepmode="backward"),
            dict(count=6, label="6m", step="month", stepmode="backward"),
            dict(count=1, label="YTD", step="year", stepmode="todate"),
            dict(count=1, label="1y", step="year", stepmode="backward"),
            dict(step="all")
        ])
    )
)
fig.add_shape(
        # Rectangle reference to the axes
            type="rect",
            xref="x",
            yref="y",
            x0=first_date,
            y0=min_value,
            x1=last_date,
            y1=0,
            opacity=0.2,
            fillcolor="Red",
        )
fig.add_shape(
        # Line Vertical
        dict(
            type="line",
            x0=cash_out_date,
            y0=min_value,
            x1=cash_out_date,
            y1=max_value,
            line=dict(
                color="Black",
                width=1,
                dash="dashdot",
            )
))

fig.show()

if save_graphs:
    fig.write_image("images/portfolio_index_comparisons.pdf")
In [11]:
fig = px.line(portfolio_index_day_comparison_stats, 
              x='date', y="day_pct_gain", 
              hover_data=['market_value', 'day_pct_gain'],
              color='symbol',
              title='Portfolio Index Day Comparisons')
fig.update_xaxes(
    rangeslider_visible=True,
    rangeselector=dict(
        buttons=list([
            dict(count=1, label="1m", step="month", stepmode="backward"),
            dict(count=6, label="6m", step="month", stepmode="backward"),
            dict(count=1, label="YTD", step="year", stepmode="todate"),
            dict(count=1, label="1y", step="year", stepmode="backward"),
            dict(step="all")
        ])
    )
)
fig.add_shape(
        # Line Vertical
        dict(
            type="line",
            x0=cash_out_date,
            y0=min_value,
            x1=cash_out_date,
            y1=max_value,
            line=dict(
                color="Black",
                width=1,
                dash="dashdot",
            )
))

fig.show()

if save_graphs:
    fig.write_image("images/portfolio_index_day_comparisons.pdf")
In [12]:
portfolio_index_day_stats = portfolio_index_day_comparison_stats[(portfolio_index_day_comparison_stats['symbol'] == 'PORTFOLIO') | (portfolio_index_day_comparison_stats['symbol'] == 'QQQ')]
fig = px.bar(portfolio_index_day_stats, 
              x='date', y="day_pct_gain", 
              hover_data=['market_value', 'day_pct_gain'],
              color='symbol',
              barmode='group',
              title='Portfolio Index Day Change vs. NASDAQ')
fig.update_xaxes(
    rangeslider_visible=True,
    rangeselector=dict(
        buttons=list([
            dict(count=1, label="1m", step="month", stepmode="backward"),
            dict(count=6, label="6m", step="month", stepmode="backward"),
            dict(count=1, label="YTD", step="year", stepmode="todate"),
            dict(count=1, label="1y", step="year", stepmode="backward"),
            dict(step="all")
        ])
    )
)
fig.add_shape(
        # Line Vertical
        dict(
            type="line",
            x0=cash_out_date,
            y0=min_value,
            x1=cash_out_date,
            y1=max_value,
            line=dict(
                color="Black",
                width=1,
                dash="dashdot",
            )
))

fig.show()

if save_graphs:
    fig.write_image("images/portfolio_index_day_change_vs_nasdaq.pdf")
In [13]:
min_value = portfolio_stock_comparison_stats['total_pct_gain'].min()
max_value = portfolio_stock_comparison_stats['total_pct_gain'].max()

fig = px.line(portfolio_stock_comparison_stats, 
              x='date', y="total_pct_gain", 
              hover_data=['market_value', 'total_pct_gain'],
              range_y=[min_value, max_value+1],
              color='symbol',
              title='Portfolio Stock Comparisons')
fig.update_xaxes(
    rangeslider_visible=True,
    rangeselector=dict(
        buttons=list([
            dict(count=1, label="1m", step="month", stepmode="backward"),
            dict(count=6, label="6m", step="month", stepmode="backward"),
            dict(count=1, label="YTD", step="year", stepmode="todate"),
            dict(count=1, label="1y", step="year", stepmode="backward"),
            dict(step="all")
        ])
    )
)
fig.add_shape(
        # Rectangle reference to the axes
            type="rect",
            xref="x",
            yref="y",
            x0=first_date,
            y0=min_value,
            x1=last_date,
            y1=0,
            opacity=0.2,
            fillcolor="Red",
        )
fig.add_shape(
        # Line Vertical
        dict(
            type="line",
            x0=cash_out_date,
            y0=min_value,
            x1=cash_out_date,
            y1=max_value,
            line=dict(
                color="Black",
                width=1,
                dash="dashdot",
            )
))

fig.show()

if save_graphs:
    fig.write_image("images/portfolio_stock_comparisons.pdf")
In [14]:
min_value = portfolio_watchlist_comparison_stats['total_pct_gain'].min()
max_value = portfolio_watchlist_comparison_stats['total_pct_gain'].max()

fig = px.line(portfolio_watchlist_comparison_stats, 
              x='date', y="total_pct_gain", 
              hover_data=['market_value', 'total_pct_gain'],
              range_y=[min_value, max_value+1],
              color='symbol',
              title='Portfolio Watchlist Comparisons')
fig.update_xaxes(
    rangeslider_visible=True,
    rangeselector=dict(
        buttons=list([
            dict(count=1, label="1m", step="month", stepmode="backward"),
            dict(count=6, label="6m", step="month", stepmode="backward"),
            dict(count=1, label="YTD", step="year", stepmode="todate"),
            dict(count=1, label="1y", step="year", stepmode="backward"),
            dict(step="all")
        ])
    )
)
fig.add_shape(
        # Rectangle reference to the axes
            type="rect",
            xref="x",
            yref="y",
            x0=first_date,
            y0=min_value,
            x1=last_date,
            y1=0,
            opacity=0.2,
            fillcolor="Red",
        )
fig.add_shape(
        # Line Vertical
        dict(
            type="line",
            x0=cash_out_date,
            y0=min_value,
            x1=cash_out_date,
            y1=max_value,
            line=dict(
                color="Black",
                width=1,
                dash="dashdot",
            )
))

fig.show()

if save_graphs:
    fig.write_image("images/portfolio_watchlist_comparisons.pdf")
In [15]:
min_value = portfolio_aggregated_stats['total_pct_gain'].min()
max_value = portfolio_aggregated_stats['total_pct_gain'].max()

fig = px.line(portfolio_aggregated_stats, 
              x='date', y="total_pct_gain", 
              hover_data=['invested_amount', 'market_value', 'unrealized_gain', 
                          'unrealized_pct_gain', 'realized_gain', 'realized_pct_gain', 
                          'total_gain', 'total_pct_gain'],
              color='invested_amount',
              range_y=[min_value, max_value+1],
              title='Portfolio Value by Invested Amount')
fig.update_xaxes(
    rangeslider_visible=True,
    rangeselector=dict(
        buttons=list([
            dict(count=1, label="1m", step="month", stepmode="backward"),
            dict(count=6, label="6m", step="month", stepmode="backward"),
            dict(count=1, label="YTD", step="year", stepmode="todate"),
            dict(count=1, label="1y", step="year", stepmode="backward"),
            dict(step="all")
        ])
    )
)
fig.add_shape(
        # Rectangle reference to the axes
            type="rect",
            xref="x",
            yref="y",
            x0=first_date,
            y0=min_value,
            x1=last_date,
            y1=0,
            opacity=0.2,
            fillcolor="Red",
        )
fig.add_shape(
        # Line Horizontal
            type="line",
            x0=first_date,
            y0=CASH_OUT_PCT,
            x1=last_date,
            y1=CASH_OUT_PCT,
            line=dict(
                color="Green",
                width=1,
                dash="dashdot",
            ),
    )
fig.add_shape(
        # Line Vertical
        dict(
            type="line",
            x0=cash_out_date,
            y0=min_value,
            x1=cash_out_date,
            y1=max_value,
            line=dict(
                color="Black",
                width=1,
                dash="dashdot",
            )
))

fig.show()

if save_graphs:
    fig.write_image("images/portfolio_value_invested_amount.pdf")
In [16]:
min_value = portfolio_stock_stats_combined['total_pct_gain'].min()
max_value = portfolio_stock_stats_combined['total_pct_gain'].max()

fig = px.line(portfolio_stock_stats_combined, 
              x='date', y="total_pct_gain", 
              color="symbol",
              hover_name="symbol", 
              hover_data=['invested_amount', 'market_value', 'unrealized_gain', 
                          'unrealized_pct_gain', 'realized_gain', 'realized_pct_gain', 
                          'total_gain', 'total_pct_gain', 'open', 'close', 'high', 
                          'low', 'volume', 'quantity', 'average_cost', 'company_name'],
              range_y=[min_value, max_value+1],
              height=700,
              title='Portfolio Stocks',)
fig.update_xaxes(
    rangeslider_visible=True,
    rangeselector=dict(
        buttons=list([
            dict(count=1, label="1m", step="month", stepmode="backward"),
            dict(count=6, label="6m", step="month", stepmode="backward"),
            dict(count=1, label="YTD", step="year", stepmode="todate"),
            dict(count=1, label="1y", step="year", stepmode="backward"),
            dict(step="all")
        ])
    )
)
fig.add_shape(
        # Rectangle reference to the axes
            type="rect",
            xref="x",
            yref="y",
            x0=first_date,
            y0=min_value,
            x1=last_date,
            y1=0,
            opacity=0.2,
            fillcolor="Red",
        )
fig.add_shape(
        # Line Vertical
        dict(
            type="line",
            x0=cash_out_date,
            y0=min_value,
            x1=cash_out_date,
            y1=max_value,
            line=dict(
                color="Black",
                width=1,
                dash="dashdot",
            )
))

fig.show()

if save_graphs:
    fig.write_image("images/portfolio_stocks.pdf")
In [17]:
fig = px.bar(s_composition_stats.sort_values(by='total_pct_gain', ascending=False),
             x="total_pct_gain", y="symbol", 
             title='Total Gain by Stock', 
             color="symbol",
             text="total_pct_gain",
             hover_data=['company_name'],
             orientation='h',
             height=700)

fig.show()

if save_graphs:
    fig.write_image("images/total_gain_by_stock.pdf")
In [18]:
fig = px.bar(s_composition_stats.sort_values(by='total_pct_gain', ascending=False),
             x="composition_invested", y="symbol", 
             title='Allocation by Stock', 
             color="symbol",
             text="composition_invested",
             hover_data=['company_name'],
             orientation='h',
             height=700)

fig.show()

if save_graphs:
    fig.write_image("images/allocation_by_stock.pdf")
In [19]:
fig = px.bar(c_composition_stats.sort_values(by='total_pct_gain', ascending=False),
             x="total_pct_gain", y="category", 
             title='Total Gain by Category', 
             color="category", 
             text="total_pct_gain",
             orientation='h')

fig.show()

if save_graphs:
    fig.write_image("images/total_gain_by_category.pdf")
In [20]:
allocation_solution = sdc.maximize_desired_allocation(date=last_date)
fig = px.bar(allocation_solution.sort_values(by='allocation_break_even_pct', ascending=False), 
             x="allocation_break_even", 
             y="category", 
             title='Allocation Break Even', 
             color="category", 
             text="allocation_break_even_pct",
             hover_data=['allocation_break_even'],
             orientation='h')

fig.show()

if save_graphs:
    fig.write_image("images/allocation_break_even.pdf")
In [21]:
fig = px.bar(c_composition_stats.sort_values(by='desired_allocation', ascending=False), 
             x="desired_allocation", 
             y="category", 
             title='Desired Allocation', 
             color="category", 
             text="desired_allocation", 
             orientation='h')

fig.show()

if save_graphs:
    fig.write_image("images/desired_allocation.pdf")
In [22]:
fig = px.bar(allocation_solution.sort_values(by='composition_after_reallocation', ascending=False), 
             x="composition_after_reallocation", 
             y="category", 
             title='Composition after Reallocation', 
             color="category", 
             text="composition_after_reallocation",
             hover_data=['composition_after_reallocation'],
             orientation='h')

fig.show()

if save_graphs:
    fig.write_image("images/composition_after_reallocation.pdf")
In [23]:
fig = px.bar(c_composition_stats.sort_values(by='composition_invested', ascending=False), 
             x="composition_invested", 
             y="category", 
             title='Current Allocation', 
             color="category", 
             text="composition_invested", 
             orientation='h')

fig.show()

if save_graphs:
    fig.write_image("images/current_allocation.pdf")